import sys

from app.functions import *
from app.config import SysConfig
import base64
import hmac
import datetime
import random
import string
import json
from urllib.parse import quote
from urllib.parse import urlencode
from urllib import request, error


class AliDNS:
    api_url = 'https://alidns.aliyuncs.com'
    API_VERSION = "2015-01-09"

    def __init__(self, config):
        self.config = {
            'accessKeyId': config.get('secretId', ''),
            'accessKeySecret': config.get('secretKey', '')
        }

    def CreateRecord(self, domain, subDomain, recordType, value, params={}):
        data = {
            "Action": 'AddDomainRecord',
            "DomainName": domain,
            "RR": subDomain,
            "Type": recordType,
            "Value": value
        }
        if 'TTL' in params:
            data['TTL'] = str(params.get('TTL', 600))
        return self.send(data)

    def ModifyRecord(self, domain, recordId, subDomain, recordType, value, params={}):
        data = {
            "Action": 'UpdateDomainRecord',
            "DomainName": domain,
            "RecordId": str(recordId),
            "RR": subDomain,
            "Type": recordType,
            "Value": value
        }
        if 'TTL' in params:
            data['TTL'] = str(params.get('TTL', 600))
        return self.send(data)

    def DeleteRecord(self, domain, recordId):
        data = {
            "Action": 'DeleteDomainRecord',
            "DomainName": domain,
            "RecordId": str(recordId),
        }
        return self.send(data)

    def DescribeRecordList(self, domain, params={}):
        data = {
            "Action": 'DescribeDomainRecords',
            "DomainName": domain,
            "RRKeyWord": params.get('subDomain', ''),
            "TypeKeyWord": params.get('recordType', ''),
            "PageSize": "500"
        }
        return self.send(data)

    def send(self, data={}):
        commonData = {
            'Format': 'JSON',
            'Version': self.API_VERSION,
            'AccessKeyId': self.config.get('accessKeyId', ''),
            'SignatureMethod': 'HMAC-SHA1',
            'Timestamp': self.utcTime(),
            'SignatureVersion': '1.0',
            'SignatureNonce': self.createGenerateRandomString()
        }
        params = dict(commonData, **data)
        params.setdefault('Signature', self.createSign(params))
        url = self.api_url + '/?' + urlencode(params)
        return self.sendHttpRequest(url)

    def createSign(self, params, method='GET'):
        sortedUurlParam = sorted(params.items(), key=lambda x: x[0])
        tmpString = ''
        for k, v in sortedUurlParam:
            tmpString += '&' + self.percentEncode(k) + '=' + self.percentEncode(v)
        stringToSign = method + '&' + '%2F' + \
                       '&' + self.percentEncode(tmpString[1:])
        hash_bytes = self.config.get('accessKeySecret') + "&"
        h = hmac.new(hash_bytes.encode('utf-8'), stringToSign.encode('utf-8'), digestmod='SHA1')
        return base64.encodebytes(h.digest()).strip()

    @staticmethod
    def utcTime():
        return datetime.datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%SZ')

    @staticmethod
    def createGenerateRandomString(length=14):
        strList = [random.choice(string.digits) for i in range(length)]
        randomStr = ''.join(strList)
        return randomStr

    @staticmethod
    def percentEncode(str):
        res = quote(str.encode('utf-8'), '')
        res = res.replace('+', '%20')
        res = res.replace('*', '%2A')
        res = res.replace('%7E', '~')
        return res

    @staticmethod
    def sendHttpRequest(url):
        try:
            req = request.Request(url)
            resp = request.urlopen(req)
            httpCode = resp.getcode()
            responseData = resp.read()
            responseContent = json.loads(responseData.decode('utf-8'))
            if httpCode == 200:
                return funReturn(SysConfig.STATUS_CODE_SUCCESS, 'success', responseContent)
            msg = responseContent.get('Message', '')
            code = responseContent.get('Code', '')
            msg = f"{code}:{msg}" if code else msg
            return funReturn(SysConfig.STATUS_CODE_SUCCESS, msg)
        except error.HTTPError as e:
            # 当状态码不是 2xx时
            errorContent = e.read().decode("utf-8")
            errorContent = json.loads(errorContent)
            msg = errorContent.get('Message', '')
            code = errorContent.get('Code', '')
            msg = f"{code}:{msg}" if code else msg
            return funReturn(SysConfig.STATUS_CODE_INSIDEERROR, msg)
        # except error.URLError as e:
        #     # 处理网络问题或证书错误等
        #     print("URL错误:", e.reason)
        except Exception as e:
            return funReturn(SysConfig.STATUS_CODE_INSIDEERROR, str(e))
